#ifndef MATH_STRUCTDATAVECTOR
#define MATH_STRUCTDATAVECTOR

#include "XYZW.hpp"
#include "../shorcut_type.hpp"

#include <iostream>
#include <math.h>

using namespace std;




namespace Math
{


enum class RC : ushorti {REF = 0, COPY};



template <typename T, typename K = T>
class StructDataVector;

template <typename T, typename K>
ostream& operator<<(ostream& os, const StructDataVector<T,K>& right);

template <typename T, typename K>
class StructDataVector
    {
        enum class DELETE : ushorti {HARD = 0, SOFT};

        public:
            ~StructDataVector(); 
            StructDataVector(const StructDataVector<T,K>& copy);
            StructDataVector(StructDataVector<T,K>&& move);
            StructDataVector(); // zero StructDataVectorStructure"
            StructDataVector(const T* const vec);
            StructDataVector(T* vec, RC c = RC::COPY);
            StructDataVector(T* x, T* y, T* z, T* w, RC c = RC::REF);
            StructDataVector(T x, T y, T z, T w);

            RC Getref_or_copy()   const   { return ref_or_copy; }

            T&                    operator[](ushorti c);
            const T&              operator[](ushorti c) const;
            explicit              operator T*();
            explicit              operator const T*() const;


        protected:
            inline void CopyToCoord(T** vec);
            inline void CopyToCoord(const T* const vec);
            inline void FillCoordByNewT();
            inline void FillAndCopy(T** vec);
            inline void FillAndCopy(const T* const vec);
            void        DeleteSecondInstanceOfCoord();
            bool        DeleteFirstInstanceOfCoord(DELETE w = DELETE::SOFT);
            T**         Getcoord()   const   { return coord; }


        private:
            RC  ref_or_copy; 
            T** coord;

    }; // end class StructDataVector
} // end namespace Math



#include "error/Throw_StructDataVector.hpp"

#include "source/StructDataVector.cpp"



#endif
